#!/usr/bin/python3
# ******************************************************************************
# Copyright (c) Huawei Technologies Co., Ltd. 2020-2020. All rights reserved.
# licensed under the Mulan PSL v2.
# You can use this software according to the terms and conditions of the Mulan PSL v2.
# You may obtain a copy of Mulan PSL v2 at:
#     http://license.coscl.org.cn/MulanPSL2
# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
# PURPOSE.
# See the Mulan PSL v2 for more details.
# ******************************************************************************/
import os
from logger import logger
from command import command
from core import extract_repo_pull, get_project_name
import constant

# from api.build_env import OpenBuildService
from .pull_link import Pull


class InstallVerify:
    """
    rpm安装检查
    """

    shell = os.path.join(os.path.dirname(__file__), "install.sh")

    def __init__(self, arch, target_branch, ignore) -> None:
        self._arch = arch
        self._pull = None
        self._repo = None
        self._target_branch = target_branch
        self._packages = []
        self._ignore = ignore

    def _update_repo(self, branch):
        """更新repo源"""
        logger.info(f"Start updating the repo source: {branch}")
        code, _, error = command(cmds=["bash", self.shell, "update_repo", branch])
        if code:
            logger.error(f"The repo source update failed: {error}.")
        return False if code else True

    def _pull_link(self, link=True):
        """
        获取pr的关联或被关联
        当link为True时,获取关联的pr,相反则获取被关联
        """
        pull_links = Pull().relation_verify(pr_number=self._pull, repo=self._repo)
        key = "link_pr" if link else "be_link_pr"
        return [
            dict(pr=link_pr["pull"], repo=link_pr["package"])
            for link_pr in pull_links[key]
        ]

    def _download_rpms(self, download_rpms: list):
        repository = "standard_x86_64" if self._arch == "x86_64" else "standard_aarch64"
        rpms = [{repo: get_project_name(repo, pull)} for repo, pull in download_rpms]
        os.makedirs(constant.DOWNLOAD_RPM_DIR, exist_ok=True)
        for package, project in rpms:
            code, _, error = command(
                cmds=[
                    "bash",
                    self.shell,
                    "download_binarys",
                    project,
                    package,
                    repository,
                    self._arch,
                ],
                cwd=constant.DOWNLOAD_RPM_DIR,
            )
            if code:
                logger.warning(
                    f"Failed to download the rpm package,project: {project} package: {package}"
                )

    def _multiple_package_check(self):
        pass

    def install(self, pull_request, multiple, packages: list):
        """
        rpm包安装
        :param rpms: rpm包路径,可以是单个包或多个软件包列表
        :param uninstall: 安装完成后是否需要卸载rpm
        """
        try:
            self._repo, self._pull = extract_repo_pull(pull_request)
        except TypeError:
            logger.warning(f"Not a valid pull link: {pull_request}.")
            return

        # 多包安装检查
        if multiple:
            be_link_pulls = self._pull_link(link=False)
            # 获取有关联关系的软件包交集
            test_project_rpms = set(packages).intersection(
                set([rpm["repo"] for rpm in be_link_pulls])
            )
            archive_rpms = set(packages).difference(set(test_project_rpms))

            download_rpms = [
                {be_link_pr["repo"]: be_link_pr["pr"]}
                for be_link_pr in be_link_pulls
                if be_link_pr["repo"] in test_project_rpms
            ]
            # 安装归档的包
            cmds = ["bash", self.shell, "install_rpms"]

            code, _, error = command(cmds=cmds.extend(archive_rpms))
        else:
            if not self._update_repo(branch=self._target_branch):
                return
            logger.info("The repo source was updated successfully.")
            link_pulls = self._pull_link()
            download_rpms = [{self._repo: self._pull}]
            # 存在关联关系
            if link_pulls:
                download_rpms.extend(
                    [{link_pull["repo"]: link_pull["pr"]} for link_pull in link_pulls]
                )
        self._download_rpms(download_rpms)
        # 安装测试工程中的包
        command(cmds=["bash", self.shell, "install_rpms", constant.DOWNLOAD_RPM_DIR])
        # 如果是单包安装，则直接检查结果，并更新
        if not multiple:
            return
        self._multiple_package_check()
